package com.starbaba.core.utils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

import com.starbaba.core.web.constant.WebConstants;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

/**
 * Freemaker 模版工具类
 *
 * @Copyright: Copyright (c) 2006
 * @Company: Revenco Tech Ltd.
 * @anthor chenminhui<chenminhui@revenco.com>
 * @since 2011-10-9 下午03:48:25
 * @version V1.0
 *
 */
public class FreemarkerTemplateUtil {
	private static Log log = LogFactory.getLog(FreemarkerTemplateUtil.class);
	
	private static Configuration FREEMARKER_CONFIG = null;
	
	public static String TEMPLATE_DIR = "template/simple";
	
	
	/**
	 * 初始化 Freemarker Configuration实例
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2011-12-20 下午02:18:42
	 * @version V1.0
	 * @throws IOException 
	 */
	public static void init() throws Exception {
		FREEMARKER_CONFIG = new Configuration();
		FREEMARKER_CONFIG.setDefaultEncoding(WebConstants.CHARACTER_ENCODING_UTF_8);
		
		URL dirURL = FreemarkerTemplateUtil.class.getClassLoader().getResource(TEMPLATE_DIR);
		if(log.isInfoEnabled()) {
			log.info("Freemaker模版目录：" + dirURL.toURI());
		}
		
		// 加载freemarker模板文件
		FREEMARKER_CONFIG.setDirectoryForTemplateLoading(new File(dirURL.toURI()));

		// 设置对象包装器
		FREEMARKER_CONFIG.setObjectWrapper(new DefaultObjectWrapper());
		
		// 设计异常处理器
		FREEMARKER_CONFIG.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
	}
	
	public static Configuration getFreemarkerConfiguration() throws Exception {
		if(FREEMARKER_CONFIG == null) {
			init();
		}
		
		return FREEMARKER_CONFIG;
	}
	
	/**
	 *  根据模板文件生成输出
	 * @param templateName 模板名称，不能为空，如: vo.flt
	 * @param dataMap 数据
	 * @param write 输出器，不能为空
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2011-10-9 下午04:08:47
	 * @version V1.0
	 * @throws Exception 
	 *
	 */
	public static void genByTemplateFile(String templateName, Object dataMap, Writer write) throws Exception {
		Assert.isTrue(StringUtils.isNotBlank(templateName), "模板文件名不能为空！");
		Assert.notNull(write, "输出writer不能为空！");
		
		// 获取指定模板文件
		if(log.isInfoEnabled()) {
			log.info("模版文件名：" + templateName);
		}
		Template template = getFreemarkerConfiguration().getTemplate(templateName);
		Assert.notNull(template, "在目录" + TEMPLATE_DIR + "找不到模版" + templateName);
		
		
		// 最后开始生成
		template.process(dataMap, write);
		
		if(log.isInfoEnabled()) {
			log.info("根据模板文件生成输出完毕");
		}
	}
	
	/**
	 * 根据模版内容生成代码
	 * @param templateContent 模版内容，不能为null，如："欢迎：${user}"
	 * @param dataMap  数据
	 * @return String 生成后的代码
	 * @throws Exception
	 */
	public static String genContent(String templateContent, Object dataMap) throws Exception {
		Assert.notNull(templateContent, "模版内容不能为空");
		
		Configuration cfg = new Configuration();
        cfg.setTemplateLoader(new StringTemplateLoader(templateContent));   
        cfg.setDefaultEncoding(WebConstants.CHARACTER_ENCODING_UTF_8);   
        // 设计异常处理器
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
		
        Template template = cfg.getTemplate("");   
        
        String code = null;
        StringWriter writer = null;
        try {
        	writer = new StringWriter();   
            template.process(dataMap, writer);
            
            code = writer.toString();
		} finally {
			IOUtils.closeQuietly(writer);
		}
        
        
        if(log.isTraceEnabled()) {
        	log.trace("生成代码：" + code);
        }
        if(log.isInfoEnabled()) {
			log.info("根据模版内容生成代码完毕");
		}
        
        return code;
	}
}
